# import core libraries
library(tidyverse)
library(janitor)  # for cleaning the variables names in the imported data
library(readxl)   # for reading in data in an Excel format

# import libraries used for building the plot
library(waffle)
library(hrbrthemes)
library(patchwork)
library(ggtext)
library(viridisLite)
library(ggtext)

# import fonts to be used in the final figure
import_roboto_condensed()

awaiting decision of eligibility / funding allocated / rejected take out withdrawals

applications <- 2820
withdrawn <- 349
active_apps <- applications - withdrawn

ineligible <- 354

# social sector approved + private non-ACM approved 
# + private ACM and non-ACM approved
fully_approved <- 31 + 42 + 13  # this is the total # buildings 
                                # have been allocated to

awaiting_decision <- active_apps - ineligible - fully_approved

perc_awaiting_decision <- round(awaiting_decision / applications * 100, 0)

df <- tibble(status = c(rep("awaiting decision", awaiting_decision),
                        rep("funding approved", fully_approved),
                        rep("ineligible", ineligible)
                        )
             )


df <- tribble(
  ~status, ~count,
  "Awaiting decision", awaiting_decision,
  "Funding approved", fully_approved,
  "Rejected", ineligible) %>% 
  mutate(status = factor(status,
                         levels = c("Rejected", 
                                    "Awaiting decision", 
                                    "Funding approved"))
  ) %>% 
  arrange(status)
df
df %>% 
  ggplot(aes(fill = status, values = count / 10)) +
  geom_waffle(n_rows = 10, size = 0.33, colour = "white", flip = TRUE) +
  
  guides(fill = guide_legend(reverse = TRUE)) +
  
  scale_fill_manual(values = c(alpha("red", 0.5),
                               "grey35", 
                               alpha("green", 0.5)
                               )) +

  
  coord_equal() +
  labs(title = glue::glue("{perc_awaiting_decision}% of applicants to the Building Safety Fund\nare awaiting a decision"),
       subtitle = "Each square represents 10 buildings that have applied to the fund",
       caption = "Source: https://www.gov.uk/guidance/remediation-of-non-acm-buildings\nData as of 5th March 2021 ") +
  
  theme_ipsum_rc(grid="") +
  theme_enhance_waffle() +
  
  theme(text = element_text(family = "Roboto Condensed"),
        legend.text = element_text(family = "Roboto Condensed"),
        plot.margin = margin(b = 1, r = 25, l = 25),
        legend.position = "top",
        legend.title = element_blank(),
        plot.title = element_text(hjust = 0.5),
        plot.subtitle = element_text(hjust = 0.5),
        plot.caption = element_text(hjust = 0)
  )

ggsave("bsf_1.png", height = 7.5, width = 5)
# based on BSF only being for tall buildings, and building with multiple
# towers making single applications
num_lh_per_building <- 100

num_bsf_suc <- 
# social sector + private full application approved non-ACM only  
total_bst_suc <- 42 + 31 
total_bst_allocated <- 71.6e6 + 58.2e6

ave_funding_per_building <- total_bst_allocated / total_bst_suc
ave_funding_per_lh <- ave_funding_per_building / num_lh_per_building
ave_funding_per_lh
## [1] 17780.82
costs <- tribble(
  ~short_name, ~remediation, ~cost, ~funded,
  "CE", "Cladding and insulation eligible for funding", 20000, 1,
  "CI", "Cladding and insulation not eligible for funding", 10000, 0,
  "WB", "Wood balconies", 10000, 0,
  "WW", "Waking watch", 5000, 0,
  "FA", "Fire alarms", 2500, 0,
  "MC", "Missing compartmentalisation", 30000, 0
)

costs_not_eligible_for_funding <- sum(costs$cost[costs$funded == 0])

costs <- costs %>% 
  add_row(short_name = c("MF","VAT"), 
          remediation = c("Managing agents fees", "VAT"), 
          cost = c(0.1 * costs_not_eligible_for_funding, 
                   0.2 * costs_not_eligible_for_funding), 
          funded = c(0,0))

costs %>% 
  ggplot(aes(fill = remediation, values = cost / 1000)) +
  geom_waffle(n_rows = 5, size = 0.33, colour = "white", flip = TRUE) +
  
  coord_equal() +
  
  theme_ipsum_rc(grid="") +
  theme_enhance_waffle() +
  
  facet_wrap(~funded)

library(ggraph)
## Warning: package 'ggraph' was built under R version 4.0.5
library(tidygraph)
## Warning: package 'tidygraph' was built under R version 4.0.5
## 
## Attaching package: 'tidygraph'
## The following object is masked from 'package:stats':
## 
##     filter
flare$vertices
edges <- data.frame(
  from = c("required", 
           "required",
           "available BSF",
           "available BSF"),
  to = c("available BSF", 
         "available ACM",
         "allocated BSF",
         "unallocated BSF"
         )
)

nodes <- data.frame(
  node_name = c("required", "available BSF", "available ACM", "allocated BSF", "unallocated BSF"),
  size = c(500, 5, 5, 1, 4)
)

# row.names(edges) <- c(1,2,3)
# row.names(nodes) <- c(1,2,3,4)

my_graph <- tbl_graph(nodes = nodes, edges = edges)

#my_graph <- as_tbl_graph(highschool)

# nodes <- data.frame(
#   node_name = c("required", "available", "allocated"),
#   size = c(50, 5, 0.5)
# )
# row.names(nodes) <-  c(1, 2, 3)
# 
# my_graph_demo <- graph_from_data_frame(flare$edges, vertices = flare$vertices)
# 
# my_graph <- graph_from_data_frame(edges, vertices = nodes)

ggraph(my_graph, layout = 'circlepack', weight = size) +
  geom_node_circle() +
  coord_fixed() +
  theme_void()
## Non-leaf weights ignored

  # geom_edge_link() + 
  # geom_node_point(aes(colour = depth)) +
  # coord_fixed()

# nodes <- data.frame(
#   name = c("flare.analytics.cluster",
#            "flare.analytics.cluster.AgglomerativeCluster"),
#   size = c(10, 5)
# )
# 
# graph <- tbl_graph(nodes = nodes, edges = slice_head(flare$edges))
# set.seed(1)
# ggraph(graph, 'circlepack', weight = size) + 
#   # geom_node_circle(aes(fill = depth), size = 0.25, n = 50) + 
#   # coord_fixed()
#   geom_edge_link() + 
#   geom_node_point(aes(colour = depth)) +
#   coord_fixed()
library(igraph)
## Warning: package 'igraph' was built under R version 4.0.5
## 
## Attaching package: 'igraph'
## The following object is masked from 'package:tidygraph':
## 
##     groups
## The following objects are masked from 'package:dplyr':
## 
##     as_data_frame, groups, union
## The following objects are masked from 'package:purrr':
## 
##     compose, simplify
## The following object is masked from 'package:tidyr':
## 
##     crossing
## The following object is masked from 'package:tibble':
## 
##     as_data_frame
## The following objects are masked from 'package:stats':
## 
##     decompose, spectrum
## The following object is masked from 'package:base':
## 
##     union
# We need a data frame giving a hierarchical structure. Let's consider the flare dataset:
edges <- flare$edges

edges <- data.frame(
  from = c("required", "available"),
  to = c("available", "allocated")
)

nodes <- data.frame(
  node_name = c("required", "available", "allocated"),
  size = c(50, 5, 0.5)
)
 
# Usually we associate another dataset that give information about each node of the dataset:
vertices <- flare$vertices
 
# Then we have to make a 'graph' object using the igraph library:
mygraph <- graph_from_data_frame( edges, vertices=nodes )
 
# Make the plot
ggraph(mygraph, layout = 'circlepack') + 
  geom_node_circle() +
  theme_void()

library(ggforce)
## Warning: package 'ggforce' was built under R version 4.0.5
library(ggthemes)
## Warning: package 'ggthemes' was built under R version 4.0.4
library(scales)
## 
## Attaching package: 'scales'
## The following object is masked from 'package:purrr':
## 
##     discard
## The following object is masked from 'package:readr':
## 
##     col_factor
pal <- economist_pal(fill = TRUE)(6)
show_col(pal)

Gov funding - https://www.gov.uk/government/news/government-to-bring-an-end-to-unsafe-cladding-with-multi-billion-pound-intervention

Taylor Wimpey - https://www.bbc.co.uk/news/business-56250730

circles_issue <- tribble(
  ~x, ~y, ~value, ~label,
  0, 0, 50, "Government funding remains a drop in the ocean of\nBritain's £50 billion fire safety crisis"
) %>% 
  mutate(r = sqrt(value / (2 * pi)),
         y = y + r)

circles_bsf_avail <- tribble(
  ~x, ~y, ~value, ~label,
  0, 0, 5, "There is £5 billion available\n in the Government's Building Safety Fund"
) %>% 
  mutate(r = sqrt(value / (2 * pi)),
         y = y + r)

circles_bsf_allo <- tribble(
  ~x, ~y, ~value, ~label,
  0, 0, 0.2268, "Only £226.8\nmillion has\nbeen awarded",
) %>% 
  mutate(r = sqrt(value / (2 * pi)),
         y = y + r)

circles_dev <- tribble(
  ~x, ~y, ~value, ~label,
  0, 5, 0.125, "Taylor Wimpey",
  0, 5.3, 0.075, "Persimmon"
) %>% 
  mutate(r = sqrt(value / (2 * pi)))



ggplot() +
  
  geom_circle(data = circles_issue,
              mapping = aes(x0 = x, y0 = y, r = r), 
              fill = pal[1], colour = pal[1], alpha = 0.3) +
  
  # geom_text(data = circles_issue,
  #           mapping = aes(x = x, y = y + r + 0.5, label = label),
  #           family = "Roboto Condensed",
  #           fontface = "bold",
  #           colour = pal[1],
  #           size = 6) +
  
  geom_circle(data = circles_bsf_avail,
              mapping = aes(x0 = x, y0 = y, r = r),
              colour = pal[4], fill = pal[4], alpha = 0.5) +
  
  geom_text(data = circles_bsf_avail,
              mapping = aes(x = x, y = y + r + 0.55, label = label),
            family = "Roboto Condensed", colour = pal[4],
            fontface = "bold", size = 4) +
  
  geom_circle(data = circles_bsf_allo,
              mapping = aes(x0 = x, y0 = y, r = r),
              colour = pal[2], fill = pal[2], alpha = 0.7) +
  
  geom_text(data = circles_bsf_allo,
              mapping = aes(x = x, y = y + r + 0.55, label = label),
            family = "Roboto Condensed", colour = pal[2],
            fontface = "bold", size = 3.5) +

  coord_equal() +
  theme_void() +
  labs(caption = "**Sources:** Colmore Tang Construction in The Telegraph (18th April 2021)
       <br>Ministry of Housing, Communities & Local Government (5th March 2021)<br>**Data viz:** @analytics_urban",
       title = "**Government funding remains a drop in the ocean of<br>Britain's £50 billion fire safety crisis**") +
  theme(plot.margin = margin(b = 5, t = 15),
        plot.title = element_markdown(colour = pal[1], hjust = 0.5,
                                      size = 14),
        text = element_text(family = "Roboto Condensed"),
        plot.caption = element_markdown(hjust = 0)
        )

ggsave("ocean.png", width = 5, height = 6)
library(ggalluvial)
## Warning: package 'ggalluvial' was built under R version 4.0.5
head(as.data.frame(UCBAdmissions), n = 12)
basics_flow <- tribble(
  ~cost, ~paying, ~Freq, ~is_lh,
  "A", "LH", 47, TRUE,
  "A", "Dev", 2, FALSE,
  "A", "Gov", 3, FALSE
)

is_alluvia_form(basics_flow)
## Missing alluvia for some stratum combinations.
## [1] TRUE
is_alluvia_form(as.data.frame(UCBAdmissions), axes = 1:3, silent = TRUE)
## [1] TRUE
ggplot(basics_flow,
       aes(y = Freq, axis1 = cost, axis2 = paying)) +
  geom_alluvium(aes(fill= is_lh), width = 1/12) +
  geom_stratum(width = 1/12, fill = "black", color = "grey") +
  geom_label(stat = "stratum", aes(label = after_stat(stratum))) +
  scale_x_discrete(limits = c("Gender", "Dept"), expand = c(.05, .05)) +
  scale_fill_brewer(type = "qual", palette = "Set1") +
  ggtitle("UC Berkeley admissions and rejections, by sex and department")

# library
library(circlize)
## Warning: package 'circlize' was built under R version 4.0.5
## ========================================
## circlize version 0.4.12
## CRAN page: https://cran.r-project.org/package=circlize
## Github page: https://github.com/jokergoo/circlize
## Documentation: https://jokergoo.github.io/circlize_book/book/
## 
## If you use it in published research, please cite:
## Gu, Z. circlize implements and enhances circular visualization
##   in R. Bioinformatics 2014.
## 
## This message can be suppressed by:
##   suppressPackageStartupMessages(library(circlize))
## ========================================
## 
## Attaching package: 'circlize'
## The following object is masked from 'package:igraph':
## 
##     degree
# Create an edge list: a list of connections between 10 origin nodes, and 10 destination nodes:
# origin <- paste0("orig ", sample(c(1:10), 20, replace = T))
# destination <- paste0("dest ", sample(c(1:10), 20, replace = T))
# data <- data.frame(origin, destination)

# adjaceny list
ad_list <- tribble(
  ~from, ~to, ~value,
  "Gov", "BO", 3,
  "LH", "BO", 48,
  "Const", "BO", 1,
  "BO", "Const", 52
)

# Transform input data in a adjacency matrix
adjacencyData <- with(ad_list, table(from, to))
 
# Charge the circlize library
 
# Make the circular plot
chordDiagram(ad_list, transparency = 0.5, directional = 1, diffHeight = mm_h(5))

la_data <- read_csv("MHCLG_BSF_and_ACM_BSF_by_Local_Authority.csv", skip = 1)
## 
## -- Column specification --------------------------------------------------------
## cols(
##   `Local Authority` = col_character(),
##   Count = col_double()
## )
library(maps)
## Warning: package 'maps' was built under R version 4.0.5
## 
## Attaching package: 'maps'
## The following object is masked from 'package:purrr':
## 
##     map
UK <- map_data("world") %>% 
  filter(region == "UK")

background_map <- ggplot() +
  geom_polygon(data = UK,
       mapping = aes(x = long, y = lat, group = group),
       fill = "grey", alpha = 0.3) +
  theme_void() +
  coord_map() +
  ylim(50,59)

background_map

library(sf)
## Warning: package 'sf' was built under R version 4.0.5
## Linking to GEOS 3.9.0, GDAL 3.2.1, PROJ 7.2.1
cas_uas <- st_read("boundaries_2019/Counties_and_Unitary_Authorities_(December_2019)_Boundaries_UK_BUC.shp")
## Reading layer `Counties_and_Unitary_Authorities_(December_2019)_Boundaries_UK_BUC' from data source `C:\Users\chris\Desktop\Data Analysis Projects\bsf_viz\boundaries_2019\Counties_and_Unitary_Authorities_(December_2019)_Boundaries_UK_BUC.shp' using driver `ESRI Shapefile'
## Simple feature collection with 216 features and 10 fields
## Geometry type: MULTIPOLYGON
## Dimension:     XY
## Bounding box:  xmin: -116.1928 ymin: 7054.1 xmax: 655653.8 ymax: 1218618
## Projected CRS: OSGB 1936 / British National Grid
'%nin%' <- function(x,y)!('%in%'(x,y))

la_data$`Local Authority`[la_data$`Local Authority` %nin% cas_uas$ctyua19nm]
## [1] NA
library(fuzzyjoin)
## Warning: package 'fuzzyjoin' was built under R version 4.0.5
library(rnaturalearth)
## Warning: package 'rnaturalearth' was built under R version 4.0.5
library(rnaturalearthdata)
## Warning: package 'rnaturalearthdata' was built under R version 4.0.5
UK <- ne_states(geounit = "england", returnclass = "sf")

bsd_geo <- merge(st_centroid(cas_uas), la_data %>% 
                         rename(ctyua19nm = `Local Authority`)) %>% 
  arrange(Count)
## Warning in st_centroid.sf(cas_uas): st_centroid assumes attributes are constant
## over geometries of x
p <- ggplot() +

  geom_sf(data = UK, colour = "grey90", fill = "grey90") +
  
  geom_sf(data = bsd_geo,
          mapping = aes(colour = Count, size = Count,
                        label = ctyua19nm)) + 

  scale_size_continuous(range = c(1,5)) +
  scale_colour_viridis_c(option = "magma", begin = 0, end = .8, direction = -1) +
  theme_void() +
  coord_sf()
## Warning: Ignoring unknown aesthetics: label
p

ggsave("test.png", p)
## Saving 7 x 5 in image
plotly::ggplotly(p)
la_data %>% 
  na.omit() %>% 
  slice_max(order_by = Count, n = 10) %>% 
  kableExtra::kable() %>% 
  kableExtra::kable_minimal()
Local Authority Count
Tower Hamlets 293
Manchester 144
Newham 138
Westminster 125
Southwark 121
Birmingham 110
Greenwich 100
Lambeth 86
Wandsworth 86
Camden 73

Code for working out centroid coordinates (in latitude and longitude) of local authorities

st_centroid(las)

las_geometry <- st_geometry(las)

la_centroids <- st_centroid(las_geometry)

la_centroids_trans <- st_transform(la_centroids, crs = 4326)


la_centroid_coords <- as.data.frame(st_coordinates(la_centroids_trans)) %>% 
  bind_cols(lad17cd = las$lad17cd, 
            lad17nm = las$lad17nm) %>% 
  relocate(lad17cd, lad17nm) %>% 
  rename(long = X, lat = Y)

la_centroid_coords